package file

import (
	"bytes"
	"fmt"
	partner "gitee.com/binny_w/gin-partner"
	"gitee.com/binny_w/gin_starter/core"
	"gitee.com/binny_w/go-util"
	"github.com/gin-gonic/gin"
	"github.com/nfnt/resize"
	"image"
	"image/gif"
	"image/jpeg"
	"image/png"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

func upload(c *gin.Context) {
	isEditor := c.PostForm("from") == "wangeditor"
	f, err := c.FormFile("file")
	if err != nil {
		if isEditor {
			c.JSON(http.StatusOK, gin.H{
				"errno":   1,
				"message": err.Error(),
			})
		} else {
			partner.WriteJsonError(c, 700, err.Error())
		}
		return
	}
	body, err := f.Open()
	if err != nil {
		if isEditor {
			c.JSON(http.StatusOK, gin.H{
				"errno":   2,
				"message": err.Error(),
			})
		} else {
			partner.WriteJsonError(c, 701, err.Error())
		}
		return
	}
	defer body.Close()
	fName := c.PostForm("file_name")
	if fName == "" {
		fName = f.Filename
	}
	key := core.GetOssKey(util.FileExtension(fName))
	bucket := c.PostForm("bucket")
	if bucket == "" {
		bucket = core.DefaultBucket
	}
	err = core.Storage.PutLarge(c, bucket, key, body, 0)
	if err != nil {
		if isEditor {
			c.JSON(http.StatusOK, gin.H{
				"errno":   3,
				"message": err.Error(),
			})
		} else {
			partner.WriteJsonError(c, 702, err.Error())
		}
		return
	}
	if isEditor {
		c.JSON(http.StatusOK, gin.H{
			"errno": 0,
			"data": gin.H{
				"url": fmt.Sprintf(
					"%s/api/file/get?bucket=%s&key=%s",
					core.Config.GetString("host-url"),
					url.QueryEscape(bucket),
					url.QueryEscape(key),
				),
			},
		})
		return
	}
	partner.WriteJsonSuccess(c, gin.H{
		"bucket": core.DefaultBucket,
		"key":    key,
	})
}

func UploadImage(c *gin.Context) {
	f, err := c.FormFile("file")
	if err != nil {
		partner.WriteJsonError(c, 700, err.Error())
		return
	}
	if f.Size > 2*1024*1024 {
		partner.WriteJsonError(c, 707, "文件超过2M，请处理后再试！")
		return
	}
	body, err1 := f.Open()
	if err1 != nil {
		partner.WriteJsonError(c, 701, err1.Error())
		return
	}
	defer body.Close()
	img, ext, err2 := image.Decode(body)
	if err2 != nil {
		partner.WriteJsonError(c, 705, err2.Error())
		return
	}
	newImg := img
	fixedWidth, _ := strconv.Atoi(c.PostForm("width"))
	fixedHeight, _ := strconv.Atoi(c.PostForm("height"))
	bounds := img.Bounds()
	// 指定了最大宽高，生成缩略图
	if (fixedWidth > 0 && fixedHeight > 0) && (bounds.Dx() > fixedWidth || bounds.Dy() > fixedHeight) {
		newImg = resize.Thumbnail(uint(fixedWidth), uint(fixedHeight), img, resize.Lanczos3)
	}
	buf := new(bytes.Buffer)
	imgType := c.DefaultPostForm("type", ext)
	switch {
	case strings.Contains(imgType, "png"):
		err2 = png.Encode(buf, newImg)
	case strings.Contains(imgType, "gif"):
		err2 = gif.Encode(buf, newImg, nil)
	case strings.Contains(imgType, "jpeg"):
		err2 = jpeg.Encode(buf, newImg, nil)
	default:
		err2 = fmt.Errorf("非法的图片类型: %s", imgType)
	}
	if err2 != nil {
		partner.WriteJsonError(c, 706, err2.Error())
		return
	}
	fName := c.PostForm("file_name")
	if fName == "" {
		fName = f.Filename
	}
	if fName != "" {
		ext = util.FileExtension(fName)
	} else if ext != "" {
		ext = "." + ext
	}
	key := core.GetOssKey(ext)
	bucket := c.PostForm("bucket")
	if bucket == "" {
		bucket = core.DefaultBucket
	}
	// 上传至OSS
	if err = core.Storage.PutLarge(c, bucket, key, buf, 0); err != nil {
		partner.WriteJsonError(c, 702, err.Error())
		return
	}
	partner.WriteJsonSuccess(c, gin.H{
		"bucket": core.DefaultBucket,
		"key":    key,
	})
}
